﻿using System;
using System.Security.Principal;
using System.Web;

namespace System.Web.Core
{
    [Serializable]
    public class User : Entity, IPrincipal
    {
        #region Private Members

        private IIdentity identity = null;
        private Property<Guid> memberId = new Property<Guid>();
        private Property<string> avatarFileName = new Property<string>();
        private Property<byte[]> avatarContent = new Property<byte[]>();
        private EntityList roleList = new EntityList();
        private EntityList rolePermissionList = null;

        #endregion

        #region Constructors

        public User()
        {
            MemberId.Value = Guid.Empty;
        }

        #endregion

        #region Public Properties

        public IIdentity UserIdentity
        {
            get
            {
                return identity;
            }
            set
            {
                identity = value;
            }
        }
        public Property<Guid> MemberId
        {
            get
            {
                return memberId;
            }
            set
            {
                memberId = value;
            }
        }
        public string MemberName
        {
            get
            {
                HttpCookie cookie = HttpContext.Current.Request.Cookies["MemberName"];
                if (cookie != null)
                {
                    return cookie.Value;
                }
                return null;
            }
        }
        public Property<string> AvatarFileName
        {
            get
            {
                return avatarFileName;
            }
            set
            {
                avatarFileName = value;
            }
        }
        public Property<byte[]> AvatarContent
        {
            get
            {
                return avatarContent;
            }
            set
            {
                avatarContent = value;
            }
        }
        public EntityList RoleList
        {
            get
            {
                return roleList;
            }
        }
        public bool IsAnonymous
        {
            get
            {
                return EntityId.Value <= 0;
            }
        }
        public bool IsAdministrator
        {
            get
            {
                return IsInRole("系统管理员");
            }
        }
        public string Language
        {
            get
            {
                return CookieManager.GetCookieValue("UserLanguageCookie", "zh-CN");
            }
            set
            {
                CookieManager.SaveCookie("UserLanguageCookie", value, 365);
            }
        }

        #endregion

        #region Public Methods

        public void SetRoles(EntityList roles)
        {
            RoleList.Clear();
            RoleList.AddRange(roles);
        }
        public MergedPermission GetPermissions()
        {
            MergedPermission mergedPermission = new MergedPermission();

            if (rolePermissionList == null)
            {
                if (IsAnonymous)
                {
                    rolePermissionList = new EntityList();
                    foreach (Role role in Configuration.Instance.AnonymousDefaultRoleList)
                    {
                        RolePermission rolePermission = RolePermissionManager.GetRolePermission(role.EntityId.Value);
                        if (rolePermission != null)
                        {
                            rolePermissionList.Add(rolePermission);
                        }
                    }
                }
                else
                {
                    rolePermissionList = RolePermissionManager.GetUserPermissions(EntityId.Value);
                }
            }

            foreach (RolePermission rolePermission in rolePermissionList)
            {
                mergedPermission.MergeRolePermission(rolePermission);
            }

            return mergedPermission;
        }
        public MergedPermission GetPermissions(Entity entity)
        {
            MergedPermission mergedPermission = GetPermissions();

            if (entity != null && entity.IsOwner(this))
            {
                RolePermission ownerRolePermission = RolePermissionManager.GetOwnerRolePermission();
                if (ownerRolePermission != null)
                {
                    mergedPermission.MergeRolePermission(ownerRolePermission);
                }
            }

            return mergedPermission;
        }

        #endregion

        #region Implementation of IPrincipal

        public IIdentity Identity
        {
            get
            {
                return UserIdentity;
            }
        }

        public bool IsInRole(string roleName)
        {
            if (string.IsNullOrEmpty(roleName))
            {
                return false;
            }
            foreach (Role role in RoleList)
            {
                if (role.Name.Value == roleName)
                {
                    return true;
                }
            }
            return false;
        }

        #endregion
    }
}